﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FooFun.GrantFrameworks;
using DTOFrameworks;
using PhysicalDataProvider;
using FooFun.DataElements.Dtos;

namespace AccessGrant.GrantFrameworks
{
    public class PermissionQuery
    {
        static PermissionQuery query;

        public static PermissionQuery Create()
        {
            if (query == null)
            {
                query = new PermissionQuery();
            }

            return query;
        }

        DEDataProvider dataProvider = new DEDataProvider();
        AccountService accountService = new AccountService();
        PermissionService pService = new PermissionService();
        ForumService forumService = new ForumService();
        PermissionSetService psService = new PermissionSetService();

        List<IEnumItem> aList = new List<IEnumItem>();
        List<IEnumItem> pList = new List<IEnumItem>();
        List<IEnumItem> fList = new List<IEnumItem>();
        PermissionCube cube = new PermissionCube();

        private PermissionQuery()
        {
            accountService.DataProvider = dataProvider;
            pService.DataProvider = dataProvider;
            forumService.DataProvider = dataProvider;
            psService.DataProvider = dataProvider;


            dataProvider.Begin();

            IDataElement aDe;
            IDataElement pDe;
            IDataElement fDe;
            IDataElement psDe;

            aDe = accountService.ListAccount();
            pDe = pService.ListPermission();
            fDe = forumService.ListForum();
            psDe = psService.ListPermissionSet();

            dataProvider.End();

            aList = new List<IEnumItem>();
            foreach (IEnumItem item in aDe)
            {
                aList.Add(item);
            }

            pList = new List<IEnumItem>();
            foreach (IEnumItem item in pDe)
            {
                pList.Add(item);
            }

            fList = new List<IEnumItem>();
            foreach (IEnumItem item in fDe)
            {
                fList.Add(item);
            }

            cube = new PermissionCube();
            foreach (IDataElement de in psDe)
            {
                cube[
                    DataProviderUtil.GetGuid(de["AccountId"].Value),
                    DataProviderUtil.GetGuid(de["PermissionId"].Value),
                    DataProviderUtil.GetGuid(de["ForumId"].Value)]
                    = GetSet(de["PermissionSet"].Value);
            }
        }

        PermissionSet GetSet(object obj)
        {
            if (obj == null)
            {
                return PermissionSet.NotSet;
            }

            bool r = (bool)obj;
            if (r)
            {
                return PermissionSet.Grant;
            }

            return PermissionSet.Revoke;
        }

        public PermissionSet this[IEnumItem obj,
            IEnumItem account,
            IEnumItem per]
        {
            get
            {
                PermissionSet set = cube[account.Id, per.Id, obj.Id];
                return set;
            }
        }

        public IMatrix<IEnumItem, IEnumItem, IEnumItem> GetMatrixByObj(IEnumItem obj)
        {
            return null;
        }

        #region 单个EnumItem获取

        private IEnumItem GetItemFromList(string name, IEnumerable<IEnumItem> list)
        {
            foreach (var item in list)
            {
                if (item.Name == name)
                {
                    return item;
                }
            }
            return null;
        }

        private IEnumItem GetItemFromList(Guid id, IEnumerable<IEnumItem> list)
        {
            foreach (var item in list)
            {
                if (item.Id == id)
                {
                    return item;
                }
            }
            return null;
        }

        public IEnumItem GetAccountByName(string name)
        {
            return GetItemFromList(name, aList);
        }

        public IEnumItem GetPermissionByName(string name)
        {
            return GetItemFromList(name, pList);
        }

        public IEnumItem GetObjectByName(string name)
        {
            return GetItemFromList(name, fList);
        }

        public IEnumItem GetAccountById(Guid id)
        {
            return GetItemFromList(id, aList);
        }

        public IEnumItem GetPermissionById(Guid id)
        {
            return GetItemFromList(id, pList);
        }

        public IEnumItem GetObjectById(Guid id)
        {
            return GetItemFromList(id, fList);
        }

        #endregion

        public IEnumerable<IEnumItem> ListAccount()
        {
            return aList;
        }

        public IEnumerable<IEnumItem> ListPermission()
        {
            return pList;
        }

        public IEnumerable<IEnumItem> ListObject()
        {
            return fList;
        }
    }

    public class PermissionCube
    {
        public PermissionCube()
        {
            dic = new Dictionary<string, PermissionSet>();
        }

        public PermissionSet this[Guid obj, Guid account, Guid per]
        {
            get
            {
                string key = GetKey(obj, account, per);
                if (dic.ContainsKey(key))
                {
                    PermissionSet set = dic[GetKey(obj, account, per)];
                    return set;
                }
                else
                {
                    return PermissionSet.NotSet;
                }
            }
            set
            {
                dic[GetKey(obj, account, per)] = value;
            }
        }

        string GetKey(Guid obj, Guid account, Guid per)
        {
            string[] strs = new string[]
            {
                obj.ToString(),account.ToString(),per.ToString()
            };
            return string.Join(",", strs);
        }

        Dictionary<string, PermissionSet> dic;
    }
}
